﻿using System.Xml.Linq;
using DVK.SP2007;
using System.Text;
using System;
using DVK.SP2007.UniversalClient.DataAccess;

namespace DVK.SP2007.UniversalClient
{
    /// <summary>
    /// Factory to create instances of IDvkMessage from dhl_message or other inputs.
    /// </summary>
    public static class DvkMessageFactory
    {
        /// <summary>
        /// Creates the IDvkMessage instance from dhl_message.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <returns></returns>
        public static IDvkMessage CreateMessage(dhl_message message)
        {
            var result = new DvkMessage();
            result.DhlId = message.dhl_id;
            result.CaseName = message.case_name;
            result.FolderName = message.dhl_folder_name;
            result.Id = message.dhl_message_id;
            result.IsIncoming = message.is_incoming == 1 ? true : false;
            result.LocalItemId = message.local_item_id;
            result.MetaXml = string.IsNullOrEmpty(message.metaxml) ? null : XElement.Parse(message.metaxml);
            result.Recipient = new SenderReceiverInfo() {
                                    Organisation = new UnitInfo() { Name = message.recipient_org_name, Code = message.recipient_org_code },
                                    Person = new UnitInfo() { Name = message.recipient_name, Code = message.recipient_person_code }
                                };
            result.Sender = new SenderReceiverInfo()
                            {
                                Organisation = new UnitInfo() { Name = message.sender_org_name, Code = message.sender_org_code },
                                Person = new UnitInfo() { Name = message.sender_name, Code = message.sender_person_code }
                            };

            result.SendingDate = message.sending_date;
            if (message.status_update_needed.HasValue)
                result.StatusUpdateNeeded = message.status_update_needed == 1 ? true : false;
            if (message.recipient_status_id.HasValue)
                result.RecipientStatus = (DvkRecipientStatus)message.recipient_status_id.Value;
            result.SendingStatus = (DvkSendingStatus)message.sending_status_id;
            result.SendingDate = message.sending_date;
            result.Title = message.title;
            result.UnitId = message.unit_id;
            result.ReceivedDate = message.received_date;
            if (!string.IsNullOrEmpty(message.fault_code))
            {
                result.Fault = new DvkFault(message.fault_actor, message.fault_code, message.fault_string, message.fault_detail);
            }

            HandleDvkXmlOn(message, result);

            return result;
        }

        /// <summary>
        /// Creates DvkXml for DvkMessage. Changes the object state.
        /// 
        /// Looks up SignedDoc from data xml.
        /// Removes SignedDoc element from data xml.
        /// Parses data xml to DvkXml on message
        /// Adds SignedDoc as binary to DvkXml object on message.
        /// </summary>
        private static void HandleDvkXmlOn(dhl_message ukMessage, IDvkMessage dvkMessage)
        {
            //Lookup SignedDoc element
            var startElement = "<SignedDoc";
            var endElement = "</SignedDoc>";
            var signedDocStartLocation = ukMessage.data.IndexOf(startElement);
            var signedDocPartLength = (ukMessage.data.IndexOf(endElement) - ukMessage.data.IndexOf(startElement)) + endElement.Length;

            var signedDocument = ukMessage.data.Substring(
                            signedDocStartLocation,
                            signedDocPartLength
                            );
            signedDocument = ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + Environment.NewLine) + signedDocument;

            //Remove SignedDoc element from data xml
            ukMessage.data.Remove(signedDocStartLocation, signedDocPartLength);

            //Parse data xml to DvkXml on message
            dvkMessage.DataXml = new DvkXml(ukMessage.data);

            //Add SignedDoc as binary to DvkXml object on message.
            dvkMessage.DataXml.SignedDocInBytes = new UTF8Encoding().GetBytes(signedDocument);
        }
    }
}
